using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using LitJson;
using NPOI.SS.Formula.Functions;
using System.IO;
using System;
using System.IO.Compression;
using System.Text;

public class ExcelTool : MonoBehaviour
{

    private static ExcelTool instance;
    public static ExcelTool GetInstance() { return instance; }

    #region     ---------->UI部分开始<----------

    /// <summary>
    /// Excel路径
    /// </summary>
    public PathSelect excel_path;
    /// <summary>
    /// Json导出路径
    /// </summary>
    public PathSelect json_path;
    /// <summary>
    /// 代码导出路径
    /// </summary>
    public PathSelect script_path;
    /// <summary>
    /// 导出代码类型（支持Unity、CocosCreator和LayaAir2.x）
    /// </summary>
    private Dropdown export_type;
    /// <summary>
    /// 是否导出代码
    /// </summary>
    private Dropdown script_type;
    /// <summary>
    /// 工程设置（名称、添加、删除）
    /// </summary>
    private ProjectSet project_set;
    /// <summary>
    /// 是否压缩Json
    /// </summary>
    private Toggle is_compress;
    /// <summary>
    /// 项目列表
    /// </summary>
    public ScrollerManager project_scorller;

    #endregion  ---------->UI部分结束<----------

    protected void Awake()
    {
        Screen.SetResolution(960, 720, false);
        if (PlayerPrefs.HasKey("PROJECTDATA"))
        {
            Utils.project_dict = JsonMapper.ToObject<Dictionary<string, Data>>(PlayerPrefs.GetString("PROJECTDATA"));
        }
        else
        {
            Utils.project_dict = new Dictionary<string, Data>();
        }
    }

    protected void Start()
    {
        instance = this;
        InitUI();
    }

    /// <summary>
    /// 初始化UI
    /// </summary>
    private void InitUI()
    {
        json_path = transform.Find("json_path").GetComponent<PathSelect>();
        excel_path = transform.Find("excel_path").GetComponent<PathSelect>();
        script_path = transform.Find("script_path").GetComponent<PathSelect>();
        project_set = transform.Find("project_set").GetComponent<ProjectSet>();

        is_compress = transform.Find("is_compress").GetComponent<Toggle>();

        export_type = transform.Find("export_type").GetComponent<Dropdown>();
        script_type = transform.Find("script_type").GetComponent<Dropdown>();

        project_scorller = transform.Find("project_scorller").GetComponent<ScrollerManager>();

        Button btn_export = transform.Find("btn_export").GetComponent<Button>();
        btn_export.onClick.AddListener(OnExportClick);
    }

    /// <summary>
    /// 显示项目设置
    /// </summary>
    public void ShowProject(string proj_name, Data data)
    {
        if (!data.json_path.EndsWith("\\") && !data.json_path.EndsWith("/")) data.json_path += "\\";
        if (!data.excel_path.EndsWith("\\") && !data.excel_path.EndsWith("/")) data.excel_path += "\\";
        if (!data.script_path.EndsWith("\\") && !data.script_path.EndsWith("/")) data.script_path += "\\";

        excel_path.SetPath(data.excel_path);
        json_path.SetPath(data.json_path);
        script_path.SetPath(data.script_path);

        script_type.value = data.script_type;
        export_type.value = data.out_type;

        is_compress.isOn = data.is_compress;

        project_set.SetName(proj_name);
    }

    /// <summary>
    /// 保存项目设置数据
    /// </summary>
    public void SaveData()
    {
        if (!string.IsNullOrEmpty(project_set.GetName()))
        {
            Data data = new Data
            {
                excel_path = excel_path.GetPath(),
                json_path = json_path.GetPath(),
                script_path = script_path.GetPath(),
                script_type = script_type.value,
                out_type = export_type.value,
                is_compress = is_compress.isOn
            };

            if (Utils.project_dict.ContainsKey(project_set.GetName()))
            {
                Utils.project_dict[project_set.GetName()] = data;
            }
            else
            {
                Utils.project_dict.Add(project_set.GetName(), data);
            }
            PlayerPrefs.SetString("PROJECTDATA", JsonMapper.ToJson(Utils.project_dict));
            project_scorller.InitScroller();
        }
    }

    /// <summary>
    /// 删除项目设置数据
    /// </summary>
    public void DeleteData()
    {
        if (!string.IsNullOrEmpty(project_set.GetName()))
        {
            if (Utils.project_dict.ContainsKey(project_set.GetName()))
            {
                Utils.project_dict.Remove(project_set.GetName());
                PlayerPrefs.SetString("PROJECTDATA", JsonMapper.ToJson(Utils.project_dict));
                project_scorller.InitScroller();
            }

            excel_path.SetPath("");
            json_path.SetPath("");
            script_path.SetPath("");

            script_type.value = 0;
            export_type.value = 0;

            is_compress.isOn = true;

            project_set.SetName("");
        }
    }

    /// <summary>
    /// 点击导出按钮
    /// </summary>
    public void OnExportClick()
    {
        if (string.IsNullOrEmpty(excel_path.GetPath()))
        {
            LogTool.WriteError("Excel路径不能为空!");
            return;
        }
        if (string.IsNullOrEmpty(json_path.GetPath()))
        {
            LogTool.WriteError("Json导出路径不能为空!");
            return;
        }
        if (script_type.value == 0 && string.IsNullOrEmpty(script_path.GetPath()))
        {
            LogTool.WriteError("代码导出路径不能为空!");
            return;
        }

        if (!json_path.GetPath().EndsWith("\\") && !json_path.GetPath().EndsWith("/")) json_path.SetPath(json_path.GetPath() + "\\");
        if (!excel_path.GetPath().EndsWith("\\") && !excel_path.GetPath().EndsWith("/")) excel_path.SetPath(excel_path.GetPath() + "\\");
        if (!script_path.GetPath().EndsWith("\\") && !script_path.GetPath().EndsWith("/")) script_path.SetPath(script_path.GetPath() + "\\");


        if (!Directory.Exists(excel_path.GetPath()))
        {
            Directory.CreateDirectory(excel_path.GetPath());
        }

        if (!Directory.Exists(json_path.GetPath()))
        {
            Directory.CreateDirectory(json_path.GetPath());
        }

        if (!Directory.Exists(script_path.GetPath()))
        {
            Directory.CreateDirectory(script_path.GetPath());
        }

        List<ExcelData> excel_data = ExcelHandle.ReadExcel(excel_path.GetPath());

        if (is_compress.isOn)
        {
            Dictionary<string, List<List<object>>> dict = new Dictionary<string, List<List<object>>>();
            for (int i = 0; i < excel_data.Count; i++)
            {
                if (dict.ContainsKey(excel_data[i].name))
                {
                    LogTool.WriteError("Excel表名重复: " + excel_data[i].name);
                }
                else
                {
                    dict.Add(excel_data[i].name, excel_data[i].values);
                }
            }
            string content = JsonMapper.ToJson(dict);
            Debug.Log(content);
            byte[] bytes = CompressString(content);
            content = Convert.ToBase64String(bytes);
            FileHandle.SaveFile(content, json_path.GetPath() + "/config.bin");
            LogTool.WriteLog($"导出配置: config.bin");

            if (script_type.value == 0)
                switch (export_type.value)
                {
                    case 0:
                        UnityScriptHandle csharp = new UnityScriptHandle();
                        csharp.ExportCompressScript(excel_data, script_path.GetPath());
                        break;
                    case 1:
                        CC2ScriptHandle cc2 = new CC2ScriptHandle();
                        cc2.ExportCompressScript(excel_data, script_path.GetPath());
                        break;
                    case 2:
                        CC3ScriptHandle cc3 = new CC3ScriptHandle();
                        cc3.ExportCompressScript(excel_data, script_path.GetPath());
                        break;
                    case 3:
                        Laya2ScriptHandle laya2 = new Laya2ScriptHandle();
                        laya2.ExportCompressScript(excel_data, script_path.GetPath());
                        break;
                }
        }
        else
        {
            for (int i = 0; i < excel_data.Count; i++)
            {
                ExcelData data = excel_data[i];
                //保存Json文件
                FileHandle.SaveFile(JsonMapper.ToJson(data.values), json_path.GetPath() + "/" + data.name + ".json");
                LogTool.WriteLog($"导出配置: {data.name}.json");
            }

            if (script_type.value == 0)
                switch (export_type.value)
                {
                    case 0:
                        UnityScriptHandle csharp = new UnityScriptHandle();
                        csharp.ExportScript(excel_data, script_path.GetPath());
                        break;
                    case 1:
                        CC2ScriptHandle cc2 = new CC2ScriptHandle();
                        cc2.ExportScript(excel_data, script_path.GetPath());
                        break;
                    case 2:
                        CC3ScriptHandle cc3 = new CC3ScriptHandle();
                        cc3.ExportScript(excel_data, script_path.GetPath());
                        break;
                    case 3:
                        Laya2ScriptHandle laya2 = new Laya2ScriptHandle();
                        laya2.ExportScript(excel_data, script_path.GetPath());
                        break;
                }
        }

    }

    /// <summary>
    /// 压缩字符串
    /// </summary>
    /// <param name="filePath">输出位置</param>
    public byte[] CompressString(string input)
    {
        using (MemoryStream outputStream = new MemoryStream())
        {
            using (GZipStream gzip = new GZipStream(outputStream, System.IO.Compression.CompressionLevel.Optimal))
            {
                using (StreamWriter writer = new StreamWriter(gzip, Encoding.UTF8))
                {
                    writer.Write(input);
                }
            }
            return outputStream.ToArray();
        }
    }

    /// <summary>
    /// 从字节数组解压缩字符串
    /// </summary>
    /// <param name="filePath">输出位置</param>
    public string DecompressBytes(byte[] compressedBytes)
    {
        using (MemoryStream inputStream = new MemoryStream(compressedBytes))
        {
            using (GZipStream gzip = new GZipStream(inputStream, CompressionMode.Decompress))
            {
                using (StreamReader reader = new StreamReader(gzip, Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
        }
    }

}
